package com.zycfc.zsf.boot.util.ead;

import java.io.*;

public class ByteUtils
{
    public static final short UNSIGNED_MAX_VALUE = 255;
    
    public static short toUnsigned(final byte b) {
        return (short)((b < 0) ? (256 + b) : b);
    }
    
    public static String toHexAscii(final byte b) {
        final StringWriter sw = new StringWriter(2);
        addHexAscii(b, sw);
        return sw.toString();
    }
    
    public static String toHexAscii(final byte[] bytes) {
        final int len = bytes.length;
        final StringWriter sw = new StringWriter(len * 2);
        for (int i = 0; i < len; ++i) {
            addHexAscii(bytes[i], sw);
        }
        return sw.toString();
    }
    
    public static byte[] fromHexAscii(final String s) throws NumberFormatException {
        try {
            final int len = s.length();
            if (len % 2 != 0) {
                throw new NumberFormatException("Hex ascii must be exactly two digits per byte.");
            }
            final int out_len = len / 2;
            final byte[] out = new byte[out_len];
            int i = 0;
            final StringReader sr = new StringReader(s);
            while (i < out_len) {
                final int val = 16 * fromHexDigit(sr.read()) + fromHexDigit(sr.read());
                out[i++] = (byte)val;
            }
            return out;
        }
        catch (IOException e) {
            throw new InternalError("IOException reading from StringReader?!?!");
        }
    }
    
    private static void addHexAscii(final byte b, final StringWriter sw) {
        final short ub = toUnsigned(b);
        final int h1 = ub / 16;
        final int h2 = ub % 16;
        sw.write(toHexDigit(h1));
        sw.write(toHexDigit(h2));
    }
    
    private static int fromHexDigit(final int c) throws NumberFormatException {
        if (c >= 48 && c < 58) {
            return c - 48;
        }
        if (c >= 65 && c < 71) {
            return c - 55;
        }
        if (c >= 97 && c < 103) {
            return c - 87;
        }
        throw new NumberFormatException(39 + c + "' is not a valid hexadecimal digit.");
    }
    
    private static char toHexDigit(final int h) {
        char out;
        if (h <= 9) {
            out = (char)(h + 48);
        }
        else {
            out = (char)(h + 55);
        }
        return out;
    }
}
